package com.pxst.fx.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pxst.bank.entity.SysAvailableBankEntity;
import com.pxst.bank.entity.SysBankCardEntity;
import com.pxst.bank.entity.SysBankCardFlowEntity;
import com.pxst.bank.mapper.SysAvailableBankMapper;
import com.pxst.bank.mapper.SysBankCardFlowEntityMapper;
import com.pxst.bank.mapper.SysBankCardMapper;
import com.pxst.exception.BusinessException;
import com.pxst.exception.ParamException;
import com.pxst.fi.entity.*;
import com.pxst.fi.mapper.*;
import com.pxst.fx.constants.FxConstant;
import com.pxst.fx.entity.*;
import com.pxst.fx.mapper.SysFxOrderEntityMapper;
import com.pxst.fx.mapper.SysFxOrderLogMapper;
import com.pxst.fx.req.SysFxOrderChildInfoReq;
import com.pxst.fx.req.SysFxOrderChildReq;
import com.pxst.fx.req.SysFxOrderChildRetryReq;
import com.pxst.fx.req.SysFxOrderChildStatusReq;
import com.pxst.fx.resp.SysFxOrderByIdChildResp;
import com.pxst.fx.resp.SysFxOrderByIdResp;
import com.pxst.fx.resp.SysFxOrderChildResp;
import com.pxst.fx.resp.SysFxOrderEntityResp;
import com.pxst.fx.service.SysFxOrderChildService;
import com.pxst.fx.mapper.SysFxOrderChildMapper;
import com.pxst.fx.service.SysFxOrderEntityService;
import com.pxst.merchant.entity.SysMerchantInfo;
import com.pxst.merchant.entity.SysMerchantWalletEntity;
import com.pxst.merchant.mapper.SysMerchantInfoMapper;
import com.pxst.merchant.mapper.SysMerchantWalletMapper;
import com.pxst.resp.ApiResp;
import com.pxst.resp.PageResp;
import com.pxst.utils.PageUtils;
import com.pxst.utils.SecurityFrameworkUtils;
import icu.mhb.mybatisplus.plugln.base.service.impl.JoinServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;

/**
 * @author notch
 * @description 针对表【sys_fx_order_child(Settlement_子下发订单)】的数据库操作Service实现
 * @createDate 2023-10-12 16:23:39
 */
@Service
public class SysFxOrderChildServiceImpl extends JoinServiceImpl<SysFxOrderChildMapper, SysFxOrderChildEntity>
        implements SysFxOrderChildService {

    @Autowired
    private SysFxOrderChildMapper sysFxOrderChildMapper;

    @Autowired
    private SysFxOrderEntityMapper sysFxOrderEntityMapper;

    @Autowired
    private SysFxOrderLogMapper sysFxOrderLogMapper;

    @Autowired
    private SysLogLastPageMapper sysLogLastPageMapper;

    @Autowired
    private SysBankCardMapper sysBankCardMapper;

    @Autowired
    private SysBankCardFlowEntityMapper sysBankCardFlowEntityMapper;

    @Autowired
    private SysAvailableBankMapper sysAvailableBankMapper;

    @Autowired
    private SysThirdPartyConfigMapper sysThirdPartyConfigMapper;

    @Autowired
    private SysThirdPartySettingMapper sysThirdPartySettingMapper;

    @Autowired
    private SysFiOrderMapper sysFiOrderMapper;

    @Autowired
    private SysMerchantInfoMapper sysMerchantInfoMapper;

    @Autowired
    private SysMerchantWalletMapper sysMerchantWalletMapper;

    @Autowired
    private SysBankBillMapper sysBankBillMapper;


    /**
     * 子下发分页查询
     * @param sysFxOrderEntityReq
     * @return
     */
    @Override
    public ApiResp<PageResp<SysFxOrderChildResp>> getSysFxOrderChildList(SysFxOrderChildReq sysFxOrderEntityReq) {

        // 根据条件查询子下发数据
        List<SysFxOrderChildResp> list = sysFxOrderChildMapper.getSysFxOrderChildList(sysFxOrderEntityReq);

        // 获取下发数据
        if (list == null || list.size() == 0) {
            return ApiResp.sucess(PageUtils.getPage(sysFxOrderEntityReq.getPage(), sysFxOrderEntityReq.getRp(), list));
        }
        Integer fxId = list.get(0).getFxId();
        SysFxOrderEntity fxOrderEntity = sysFxOrderEntityMapper.selectById(fxId);


        // 获取当前登录账户
        String userName = null;
        if (SecurityFrameworkUtils.getLoginUser() != null) {
            userName = SecurityFrameworkUtils.getLoginUser().getUsername();
        }
        if (userName == null) {
            throw new ParamException("获取不到登录用户,请重新登录", "500");
        }
        String finalUserName = userName;

        list.stream().map(i -> {
            // 下发状态等于3时，才有系统手续费，才有完成时间
            if (i.getStatus() != FxConstant.STATUS_COMPLETED) {
                i.setRate(null);
                i.setCreatedAt(null);
            }

            // 设置CheckButton的值
            List<SysFxOrderLogEntity> sysFxOrderLogEntities = sysFxOrderLogMapper.selectList(
                    new LambdaQueryWrapper<SysFxOrderLogEntity>().eq(SysFxOrderLogEntity::getFxOrderChildId, i.getFxChildId()));
            i.setCheckBtn(getCheckButtonStatus(sysFxOrderLogEntities, fxOrderEntity, i, finalUserName));

            //  设置RetryButton的值： true false
            i.setRetryBtn(getRetryButtonStatus(sysFxOrderLogEntities, fxOrderEntity, i, finalUserName));

            // 设置IsRunMon的值
            i.setIsRunMon(getIsRunMonStatus(i));

            // 设置isErrUrl的值
            Integer integer = sysLogLastPageMapper.selectCount(new LambdaQueryWrapper<SysLogLastPageEntity>()
                    .eq(StringUtils.isNotBlank(i.getCommandId()), SysLogLastPageEntity::getCommandId, i.getCommandId()));
            i.setIsErrUrl(integer == 0 ? false : true);

            // 设置bankreferenceno的值
            if (i.getTpiId() == null) {
                i.setBankReferenceNo(null);
            }
            // 设置Message的值
            i.setMessage(i.getMessage() + "\\nCheck: " + i.getCreatedMan() + "\\nRetry: " + i.getUpdateMan());

            return i;
        }).collect(Collectors.toList());

        return ApiResp.sucess(PageUtils.getPage(sysFxOrderEntityReq.getPage(), sysFxOrderEntityReq.getRp(), list));
    }

    /**
     * 子下发汇出报表
     *
     * @param sysFxOrderEntityReq
     * @return
     */
    @Override
    public List<SysFxOrderChildExcelModel> download(SysFxOrderChildReq sysFxOrderEntityReq) {
        // 根据条件查询子下发数据
        List<SysFxOrderChildResp> sysFxOrderChildList = sysFxOrderChildMapper.getSysFxOrderChildList(sysFxOrderEntityReq);
        // 封装到excel中
        return addDateForExcel(sysFxOrderChildList);
    }

    /**
     * 新增子下发
     *
     * @param sysFxOrderChildInfoReq
     * @return
     */
    @Override
    @Transactional
    public ApiResp create(SysFxOrderChildInfoReq sysFxOrderChildInfoReq) {

        // 通过下发Id判断是否有这个数据，没有抛出异常
        Long fxId = sysFxOrderChildInfoReq.getFxId();
        SysFxOrderEntity fxOrderEntity = sysFxOrderEntityMapper.selectById(fxId);
        if (fxOrderEntity == null) {
            throw new ParamException("fxId不存在", "404");
        }

        // 根据bcId获取对应银行卡信息，银行卡状态不为1抛出异常
        Long bcId = sysFxOrderChildInfoReq.getBcId();
        SysBankCardEntity sysBankCardEntity = sysBankCardMapper.selectById(bcId);
        if (sysBankCardEntity == null) {
            throw new ParamException("bcId不存在", "404");
        }
        if (sysBankCardEntity.getStatus() != 1) {
            throw new ParamException("该银行卡未开发成功", "500");
        }
        // 判断金额是否够交易
        if (fxOrderEntity.getBalance().compareTo(sysFxOrderChildInfoReq.getAmount()) < 0) {
            throw new ParamException("该银行卡余额不足", "500");
        }

        // 封装子下发数据
        SysFxOrderChildEntity sysFxOrderChildEntity = new SysFxOrderChildEntity();
        BeanUtils.copyProperties(sysBankCardEntity, sysFxOrderChildEntity);

        sysFxOrderChildEntity.setFxOrderMainId(sysFxOrderChildInfoReq.getFxId());
        sysFxOrderChildEntity.setVpnId(Math.toIntExact(sysBankCardEntity.getVpnId()));
        sysFxOrderChildEntity.setFromBankCardId(sysFxOrderChildInfoReq.getBcId());
        sysFxOrderChildEntity.setTxnMode(sysFxOrderChildInfoReq.getTxnMode());
        sysFxOrderChildEntity.setRequestAmount(sysFxOrderChildInfoReq.getAmount());
        sysFxOrderChildEntity.setRate(BigDecimal.valueOf(0.000000));
        if (sysFxOrderChildInfoReq.getBankFee() != null) {
            // 手动添加
            sysFxOrderChildEntity.setBankFee(sysFxOrderChildInfoReq.getBankFee());
        } else {
            // 半自动添加
            sysFxOrderChildInfoReq.setBankFee(BigDecimal.valueOf(0.000000));
        }
        sysFxOrderChildEntity.setPreBalance(fxOrderEntity.getBalance());
        sysFxOrderChildEntity.setBalance(fxOrderEntity.getBalance().subtract(sysFxOrderChildInfoReq.getAmount()));
        sysFxOrderChildEntity.setBankReferenceNo(sysFxOrderChildInfoReq.getReference());
        sysFxOrderChildEntity.setCurrency("THB");
        sysFxOrderChildEntity.setStep("[0/10]");
        sysFxOrderChildEntity.setRetryTimes(0);
        sysFxOrderChildEntity.setIsPressButton(0);
        sysFxOrderChildEntity.setStatus(1);
        sysFxOrderChildEntity.setIsRefCode(0);
        sysFxOrderChildEntity.setIsEntry(0);
        // 获取当前登录账户
        String userName = null;
        if (SecurityFrameworkUtils.getLoginUser() != null) {
            userName = SecurityFrameworkUtils.getLoginUser().getUsername();
        }
        if (userName == null) {
            throw new ParamException("获取不到登录用户,请重新登录", "500");
        }
        sysFxOrderChildEntity.setCreator(userName);
        sysFxOrderChildEntity.setUpdater(userName);
        sysFxOrderChildEntity.setCreatedAt(new Date());
        sysFxOrderChildEntity.setUpdatedAt(new Date());
        sysFxOrderChildEntity.setIsLateTimes(0);
        sysFxOrderChildEntity.setIsUrgent(0);
        sysFxOrderChildEntity.setFrozenAvailableBalance(BigDecimal.valueOf(0.000000));
        sysFxOrderChildEntity.setFrozenGuaranteeBalance(BigDecimal.valueOf(0.000000));

        sysFxOrderChildMapper.insert(sysFxOrderChildEntity);

        return ApiResp.sucess();
    }

    /**
     * 更新子下发状态
     *
     * @param sysFxOrderChildStatusReq
     * @return
     */
    @Override
    @Transactional
    public ApiResp updateStatus(SysFxOrderChildStatusReq sysFxOrderChildStatusReq) {

        // 获取子下发数据
        SysFxOrderChildEntity sysFxOrderChildEntity = sysFxOrderChildMapper.selectById(sysFxOrderChildStatusReq.getFxAltId());
        if (sysFxOrderChildEntity == null) {
            throw new ParamException("找不到子下发数据", "404");
        }

        // 子下发状态不为1和4，无法更新状态
        if (sysFxOrderChildEntity.getStatus() != 1 && sysFxOrderChildEntity.getStatus() != 4) {
            throw new BusinessException("子下发状态不为1和4");
        }

        // 获取下发数据
        SysFxOrderEntity fxOrderEntity = sysFxOrderEntityMapper.selectById(sysFxOrderChildEntity.getFxOrderMainId());

        // 通过子下发数据获取银行卡数据，再通过银行卡数据获取可用银行数据的code属性
        SysBankCardEntity sysBankCardEntity = sysBankCardMapper.selectById(sysFxOrderChildEntity.getFromBankCardId());

        if (sysFxOrderChildEntity.getTxnMode() == 1) {
            SysAvailableBankEntity sysAvailableBankEntity = sysAvailableBankMapper.selectById(sysBankCardEntity.getAvailableBankId());
            String bankCode = sysAvailableBankEntity.getBankCode();
            // 更新账户变化-->账户变化=请求金额+银行手续费
            // 若银行手续费
            List<String> list = new ArrayList<>();
            list.add("VCB");
            list.add("VTB");
            list.add("SAC");
            // 根据传来的银行费率更新请求金额
            BigDecimal requestAmount = list.contains(bankCode) ? (sysFxOrderChildEntity.getRequestAmount().add(sysFxOrderChildStatusReq.getBankFee() != null ? sysFxOrderChildStatusReq.getBankFee() : new BigDecimal(0))) : sysFxOrderChildEntity.getRequestAmount();

            if (sysFxOrderChildEntity.getStatus() == FxConstant.STATUS_COMPLETED) {
                // 获取银行对账单数据
                SysBankBillEntity sysBankBillEntity = sysBankBillMapper.selectById(sysFxOrderChildStatusReq.getVbId());
                if (sysBankBillEntity == null) {
                    throw new ParamException("找不到银行对账单数据", "404");
                }
                // 校验银行对账单数据属性
                if (sysBankBillEntity.getCommandId() == null) {
                    throw new ParamException("VBS_ID_exists", "500");
                } else if (sysBankBillEntity.getType() != 8) {
                    throw new ParamException("vb100.type_error", "500");
                } else if (sysFxOrderChildEntity.getFromBankCardId() != sysBankBillEntity.getBankCardId()) {
                    throw new ParamException("vb100.BC100_not_match", "500");
                } else if (requestAmount.compareTo(sysBankBillEntity.getDebit()) != 0) {
                    throw new ParamException("vb100.amount_error", "500");
                } else if (sysBankBillEntity.getVoid_() == null) {
                    throw new ParamException("vb100.vbs_void", "500");
                }
                // 更新银行对账单属性
                sysBankBillEntity.setCommandId(sysFxOrderChildEntity.getCommandId());
                sysBankBillEntity.setType(3);
                sysBankBillEntity.setModelClass("FX110");
                sysBankBillEntity.setMerchantId(fxOrderEntity.getMerchantId());
                sysBankBillEntity.setReference(sysBankBillEntity.getReference() == null ? fxOrderEntity.getReference() : sysBankBillEntity.getReference());
                sysBankBillEntity.setTxnMode(1);
                sysBankBillMapper.updateById(sysBankBillEntity);


                SysBankCardFlowEntity sysBankCardFlowEntity = sysBankCardFlowEntityMapper.selectOne(new LambdaQueryWrapper<SysBankCardFlowEntity>().eq(SysBankCardFlowEntity::getBankCardId, sysBankCardEntity.getId()));

                // 手动-成功后更新银行卡流水
                boolean pending = sysFxOrderChildEntity.getStatus() == FxConstant.STATUS_PENDING || sysFxOrderChildEntity.getStatus() == FxConstant.STATUS_PROCESSING;
                // 判断是否在同一天或同一个月
                Date tradeTime = sysBankBillEntity.getTradeTime();
                boolean isToday = tradeTime.getDay() == new Date().getDay();
                boolean isMonth = tradeTime.getMonth() == new Date().getMonth();

                sysBankCardFlowEntity.setTotalDayDebit(sysBankCardFlowEntity.getTotalDayDebit().add(sysFxOrderChildEntity.getRequestAmount()));
                if (isMonth) {
                    sysBankCardFlowEntity.setMonthSuccessOutCount(sysBankCardFlowEntity.getMonthSuccessOutCount() + 1);
                }
                if (isToday) {
                    sysBankCardFlowEntity.setDaySuccessOutCount(sysBankCardFlowEntity.getDaySuccessOutCount() + 1);
                }
                if (pending) {
                    sysBankCardFlowEntity.setBalance(sysBankCardFlowEntity.getBalance().subtract(sysFxOrderChildEntity.getRequestAmount()));
                    if (isMonth) {
                        sysBankCardFlowEntity.setMonthSuccessOutCount(sysBankCardFlowEntity.getMonthSuccessOutCount() - 1 > 0 ? sysBankCardFlowEntity.getMonthSuccessOutCount() - 1 : 0);
                    }
                    sysBankCardFlowEntity.setDaySuccessOutCount(sysBankCardFlowEntity.getDaySuccessOutCount() - 1 > 0 ? sysBankCardFlowEntity.getDaySuccessOutCount() - 1 : 0);
                } else {
                    sysBankCardFlowEntity.setDayFlowOut(sysBankCardFlowEntity.getDayFlowOut().add(sysFxOrderChildEntity.getRequestAmount()));
                    sysBankCardFlowEntity.setMonthFlowOut(sysBankCardFlowEntity.getMonthFlowOut().add(sysFxOrderChildEntity.getRequestAmount()));
                }
                // 更新 sysBankCardFlow数据
                sysBankCardFlowEntityMapper.updateById(sysBankCardFlowEntity);
            } else {
                if (sysFxOrderChildStatusReq.getForce() != 0) {
                    if (sysFxOrderChildEntity.getStatus() == FxConstant.STATUS_PENDING) {
                        // 手动-失败后更新银行卡钱包
                        // 获取银行对账单数据
                        SysBankBillEntity sysBankBillEntity = sysBankBillMapper.selectById(sysFxOrderChildStatusReq.getVbId());
                        // 判断是否在同一天或同一个月
                        Date tradeTime = sysBankBillEntity.getTradeTime();
                        boolean isToday = tradeTime.getDay() == new Date().getDay();
                        boolean isMonth = tradeTime.getMonth() == new Date().getMonth();
                        SysBankCardFlowEntity sysBankCardFlowEntity = sysBankCardFlowEntityMapper.selectOne(new LambdaQueryWrapper<SysBankCardFlowEntity>().eq(SysBankCardFlowEntity::getBankCardId, sysBankCardEntity.getId()));
                        sysBankCardFlowEntity.setFxFreezeAmount(sysBankCardFlowEntity.getFxFreezeAmount().subtract(sysFxOrderChildEntity.getRequestAmount()));
                        if (isToday) {
                            sysBankCardFlowEntity.setDayFlowOut(sysBankCardFlowEntity.getDayFlowOut().subtract(sysFxOrderChildEntity.getRequestAmount()));
                        }
                        sysBankCardFlowEntity.setDayFreezeSuccessOutCount(sysBankCardFlowEntity.getDayFreezeSuccessOutCount() - 1 < 0 ? 0 : sysBankCardFlowEntity.getDayFreezeSuccessOutCount() - 1);
                        if (isMonth) {
                            sysBankCardFlowEntity.setMonthFlowOut(sysBankCardFlowEntity.getMonthFlowOut().subtract(sysFxOrderChildEntity.getRequestAmount()));
                            sysBankCardFlowEntity.setMonthFreezeSuccessOutCount(sysBankCardFlowEntity.getMonthFreezeSuccessOutCount() - 1 < 0 ? 0 : sysBankCardFlowEntity.getMonthFreezeSuccessOutCount() - 1);
                        }
                        // 更新 sysBankCardFlow数据
                        sysBankCardFlowEntityMapper.updateById(sysBankCardFlowEntity);
                    }

                }
            }
        } else {
            if (sysFxOrderChildEntity.getStatus() == FxConstant.STATUS_COMPLETED) {
                SysThirdPartyConfigEntity sysThirdPartyConfigEntity = sysThirdPartyConfigMapper.selectById(sysFxOrderChildEntity.getThirdPartyConfigId());
                if (sysThirdPartyConfigEntity == null) {
                    throw new BusinessException("无法获取第三方支付配置");
                }
            }
        }
        // 更新下发数据
        if (sysFxOrderChildEntity.getStatus() == FxConstant.STATUS_COMPLETED) {
            fxOrderEntity.setPaidAmount(fxOrderEntity.getPaidAmount().subtract(sysFxOrderChildEntity.getPaidAmount()));
            if (fxOrderEntity.getRequestAmount() == fxOrderEntity.getPaidAmount()) {
                // 主单成功后更新商户钱包
                SysMerchantWalletEntity sysMerchantWalletEntity = sysMerchantWalletMapper.selectList(new LambdaQueryWrapper<SysMerchantWalletEntity>().eq(SysMerchantWalletEntity::getMerchantId, fxOrderEntity.getMerchantId())).stream().findFirst().orElse(null);
                if (fxOrderEntity.getStatus() == FxConstant.STATUS_COMPLETED) {
                    BigDecimal directAmount = fxOrderEntity.getPaidAmount().add(fxOrderEntity.getBankFee());
                    if (directAmount.compareTo(BigDecimal.ZERO) > 0) {
                        sysMerchantWalletEntity.setBalance(sysMerchantWalletEntity.getBalance().subtract(directAmount));
                        sysMerchantWalletEntity.setAvailableBalance(sysMerchantWalletEntity.getAvailableBalance().subtract(directAmount));
                    }
                    sysMerchantWalletMapper.updateById(sysMerchantWalletEntity);
                } else {
                    BigDecimal holdAmount = fxOrderEntity.getPaidAmount().add(fxOrderEntity.getBankFee());
                    if (holdAmount.compareTo(BigDecimal.ZERO) > 0) {
                        sysMerchantWalletEntity.setBalance(sysMerchantWalletEntity.getBalance().subtract(holdAmount));
                        sysMerchantWalletEntity.setFreezeBalance(sysMerchantWalletEntity.getFreezeBalance().subtract(holdAmount).compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : sysMerchantWalletEntity.getFreezeBalance().subtract(holdAmount));
                        sysMerchantWalletEntity.setFreezeAmountMain(sysMerchantWalletEntity.getFreezeAmountMain().subtract(holdAmount).compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : sysMerchantWalletEntity.getFreezeAmountMain().subtract(holdAmount));
                    }
                    sysMerchantWalletMapper.updateById(sysMerchantWalletEntity);
                }
                fxOrderEntity.setStatus(FxConstant.STATUS_COMPLETED);
                fxOrderEntity.setBalance(sysMerchantWalletEntity.getBalance());
                fxOrderEntity.setCompletedAt(new Date());
                sysFxOrderEntityMapper.updateById(fxOrderEntity);
            }

        }
        // 重新获取返回类数据SysFxOrderChildResp
        SysFxOrderChildResp sysFxOrderChildResp=sysFxOrderChildMapper.getSysFxOrderChild(sysFxOrderChildStatusReq.getFxAltId());

        return ApiResp.sucess(sysFxOrderChildResp);
    }


    /**
     * 子下发确认按钮
     *
     * @param id
     * @return
     */
    @Override
    @Transactional
    public ApiResp check(Long id) {

        // 获取当前登录账户
        String userName = null;
        if (SecurityFrameworkUtils.getLoginUser() != null) {
            userName = SecurityFrameworkUtils.getLoginUser().getUsername();
        }
        if (userName == null) {
            throw new ParamException("获取不到登录用户,请重新登录", "500");
        }
        // 根据子下发id查询下发和子下发数据
        SysFxOrderChildEntity sysFxOrderChildEntity = sysFxOrderChildMapper.selectById(id);
        SysFxOrderEntity fxOrderEntity = sysFxOrderEntityMapper.selectById(sysFxOrderChildEntity.getFxOrderMainId());

        // 获取子下发操作表数据
        List<SysFxOrderLogEntity> sysFxOrderLogEntities = sysFxOrderLogMapper.selectList(new LambdaQueryWrapper<SysFxOrderLogEntity>().eq(SysFxOrderLogEntity::getFxOrderChildId, id));

        // 判断子下发是否已经被确认过
        if (sysFxOrderChildEntity.getStatus() == 4 && sysFxOrderChildEntity.getIsPressButton() == 0
                && sysFxOrderChildEntity.getRetryTimes() < 2 && sysFxOrderChildEntity.getAction() == null
                && (fxOrderEntity.getStatus() == 1 || fxOrderEntity.getStatus() == 2)) {
            throw new ParamException("子下发已有确认记录", "500");

        } else {
            if (sysFxOrderLogEntities != null && sysFxOrderLogEntities.stream().allMatch(item -> item.getType() != 0)) {
                // 添加确认记录
                SysFxOrderLogEntity sysFxOrderLogEntity = new SysFxOrderLogEntity();
                sysFxOrderLogEntity.setFxOrderChildId(id);
                sysFxOrderLogEntity.setType(0);
                sysFxOrderLogEntity.setCreator(userName);
                sysFxOrderLogEntity.setUpdater(userName);
                sysFxOrderLogEntity.setCreatedAt(new Date());
                sysFxOrderLogEntity.setUpdatedAt(new Date());
                sysFxOrderLogMapper.insert(sysFxOrderLogEntity);
            } else {
                throw new ParamException("子下发已有确认记录", "500");
            }
        }
        // 更新下发和子下发的更新数据
        fxOrderEntity.setUpdatedMan(userName);
        sysFxOrderChildEntity.setUpdater(userName);
        fxOrderEntity.setUpdatedAt(new Date());
        sysFxOrderChildEntity.setUpdatedAt(new Date());

        sysFxOrderEntityMapper.updateById(fxOrderEntity);
        sysFxOrderChildMapper.updateById(sysFxOrderChildEntity);

        // 重新获取返回类数据SysFxOrderChildResp
        SysFxOrderChildResp sysFxOrderChildResp=sysFxOrderChildMapper.getSysFxOrderChild(id);

        return ApiResp.sucess(sysFxOrderChildResp);
    }


    /**
     * 子下发刷新按钮
     *
     * @param id
     * @return
     */
    @Override
    public ApiResp runMon(Long id) {

        // 根据id获取子下发信息
        SysFxOrderChildEntity sysFxOrderChildEntity = sysFxOrderChildMapper.selectById(id);

        // 获取第三方支付配置
        SysThirdPartyConfigEntity sysThirdPartyConfigEntity = sysThirdPartyConfigMapper.selectById(sysFxOrderChildEntity.getThirdPartyConfigId());

        boolean isRunmon;
        boolean isTpi = sysThirdPartyConfigEntity.getId() != null && sysThirdPartyConfigEntity.getId() > 0;
        if (isTpi) {
            isRunmon = (sysFxOrderChildEntity.getStatus() == FxConstant.STATUS_PENDING || sysFxOrderChildEntity.getStatus() == FxConstant.STATUS_PROCESSING || sysFxOrderChildEntity.getStatus() == FxConstant.STATUS_MANUAL_PROCESS) && getDateDiff(sysFxOrderChildEntity.getCreatedAt()) >= 60;
        } else {
            isRunmon = (sysFxOrderChildEntity.getStatus() == FxConstant.STATUS_PENDING || sysFxOrderChildEntity.getStatus() == FxConstant.STATUS_PROCESSING) && getDateDiff(sysFxOrderChildEntity.getUpdatedAt()) >= 900;
        }
        if (!isRunmon) {
            ApiResp.paramError("订单状态异常，无法刷新");
        }
        if (isTpi) {
            // 根据tx_mode属性找到第三方支付方式
            // TODO:目前只有VNPAY的支付方式
//          String thirdPartyPaymentMethod = getThirdPartyPaymentMethod(sysFxOrderChildEntity.getTxnMode());
            SysThirdPartyConfigEntity vnPayConfig = sysThirdPartyConfigMapper.selectOne(new LambdaQueryWrapper<SysThirdPartyConfigEntity>().eq(SysThirdPartyConfigEntity::getDriver, "vnpay"));

            // 检查订单状态
            // 根据第三方配置Id获取充值订单
            List<SysFiOrderEntity> sysFiOrderEntities = sysFiOrderMapper.selectList(new LambdaQueryWrapper<SysFiOrderEntity>().eq(SysFiOrderEntity::getThirdPartyConfigId, sysThirdPartyConfigEntity.getId()));
            if (sysFiOrderEntities == null || sysFiOrderEntities.size() == 0) {
                throw new BusinessException("充值订单不存在");
            }
            // 判断是否有第三方支付配置
            if (sysThirdPartyConfigEntity == null) {
                throw new ParamException("第三方支付配置不存在", "404");
            }
            // TODO:调用VnpayApiDispatcher发送请求并获取一个JSON对象
            // 根据JSON对象的status执行相应操作

            return ApiResp.sucess();
        }
        // 点击次数计数
        if (sysFxOrderChildEntity.getRunmonNumber() < 3) {
            sysFxOrderChildEntity.setRunmonNumber(sysFxOrderChildEntity.getRunmonNumber() + 1);
        } else {
            isRunmon = false;
        }
        boolean isApp = sysFxOrderChildEntity.getVndPaymentMethod().toLowerCase(Locale.ROOT).equals("app");
        if (isRunmon) {
            if (isApp) {
                // TODO:调用VnpayApiDispatcher发送请求并获取一个JSON对象
            }
        }else {
            // 根据状态执行相应操作

        }
        // 重新获取返回类数据SysFxOrderChildResp
        SysFxOrderChildResp sysFxOrderChildResp=sysFxOrderChildMapper.getSysFxOrderChild(id);

        return ApiResp.sucess(sysFxOrderChildResp);
    }

    /**
     * 子下发重试按钮
     * @param sysFxOrderChildRetryReq
     * @return
     */
    @Override
    public ApiResp retry(SysFxOrderChildRetryReq sysFxOrderChildRetryReq) {
        // 根据子下发id查询子下发数据
        SysFxOrderChildEntity sysFxOrderChildEntity = sysFxOrderChildMapper.selectById(sysFxOrderChildRetryReq.getFxAltId());
        if (sysFxOrderChildEntity == null){
            throw new ParamException("子下发数据不存在", "404");
        }
        // 检查子下发是否可以重试
        // 获取sys_fx_order_log表中的数据
        SysFxOrderLogEntity sysFxOrderLogEntity = sysFxOrderLogMapper.selectOne(new LambdaQueryWrapper<SysFxOrderLogEntity>().eq(SysFxOrderLogEntity::getFxOrderChildId, sysFxOrderChildEntity.getId()));

        // 获取当前登录账户
        String userName = null;
        if (SecurityFrameworkUtils.getLoginUser() != null) {
            userName = SecurityFrameworkUtils.getLoginUser().getUsername();
        }
        if (userName == null) {
            throw new ParamException("获取不到登录用户,请重新登录", "500");
        }

        if (!retryReady(sysFxOrderChildEntity)&&(sysFxOrderLogEntity.getType()==0&&!sysFxOrderLogEntity.getCreator().equals(userName))){
            throw new BusinessException("不满足重试条件");
        }

        // 根据bcId查询数据,并验证pgId的正确性
        if (sysFxOrderChildRetryReq.getBcId()!=null){
            SysBankCardEntity sysBankCardEntity = sysBankCardMapper.selectById(sysFxOrderChildRetryReq.getBcId());
            // 根据子下发数据查询下发数据中的shId查询商户信息
            SysFxOrderEntity fxOrderEntity = sysFxOrderEntityMapper.selectById(sysFxOrderChildEntity.getFxOrderMainId());
            SysMerchantInfo sysMerchantInfo = sysMerchantInfoMapper.selectById(fxOrderEntity.getMerchantId());
            if (sysBankCardEntity.getBankCardGroupId()!=sysMerchantInfo.getBankGroupId()){
                throw new ParamException("传入的参数对应数据不存在","500");
            }
            // 检查银行限额
            // 获取银行可用系统数据
            SysAvailableBankEntity sysAvailableBankEntity = sysAvailableBankMapper.selectById(sysBankCardEntity.getAvailableBankId());
            if (sysAvailableBankEntity!=null){
                if (sysAvailableBankEntity.getFxMax().compareTo(sysFxOrderChildEntity.getRequestAmount())<0){
                    throw new BusinessException("请求金额不能超过最大下发数");
                }
                if (sysAvailableBankEntity.getFxMin().compareTo(sysFxOrderChildEntity.getRequestAmount())>0){
                    throw new BusinessException("请求金额不能小于最小下发数");
                }
            }
            // 获取银行卡流水数据
            SysBankCardFlowEntity bankCardFlowEntity = sysBankCardFlowEntityMapper.selectById(sysBankCardEntity.getId());
            Integer monthRemain=sysBankCardEntity.getMonthThresholdMax()-bankCardFlowEntity.getMonthSuccessInCount()-bankCardFlowEntity.getMonthFreezeSuccessInCount()-bankCardFlowEntity.getMonthSuccessOutCount()-bankCardFlowEntity.getMonthFreezeSuccessOutCount();

            if (monthRemain<=0){
                throw new BusinessException("超过月次数最大限制");
            }
            BigDecimal realBalance=bankCardFlowEntity.getBalance().subtract(sysBankCardEntity.getMinReservedAmount());
            if (realBalance.compareTo(sysFxOrderChildEntity.getRequestAmount())<0){
                throw new BusinessException("请求金额异常");
            }
            if (sysBankCardEntity.getDayStreamOutMax().subtract(bankCardFlowEntity.getDayFlowOut()).compareTo(sysFxOrderChildEntity.getRequestAmount())<0){
                throw new BusinessException("请求金额异常");
            }
            if (sysBankCardEntity.getMonthStreamOutMax().subtract(bankCardFlowEntity.getMonthFlowOut()).compareTo(sysFxOrderChildEntity.getRequestAmount())<0){
                throw new BusinessException("请求金额异常");
            }
            // 更新银行流水
            SysBankCardFlowEntity sysBankCardFlowEntity = sysBankCardFlowEntityMapper.selectById(sysBankCardEntity.getId());
            sysBankCardFlowEntity.setFxFreezeAmount(sysBankCardFlowEntity.getFxFreezeAmount().add(sysFxOrderChildEntity.getRequestAmount()));
            sysBankCardFlowEntity.setDayFlowOut(sysBankCardFlowEntity.getDayFlowOut().add(sysFxOrderChildEntity.getRequestAmount()));
            sysBankCardFlowEntity.setMonthFlowOut(sysBankCardFlowEntity.getMonthFlowOut().add(sysFxOrderChildEntity.getRequestAmount()));
            sysBankCardFlowEntity.setDaySuccessInCount(sysBankCardFlowEntity.getDaySuccessOutCount()+1);
            sysBankCardFlowEntity.setDayFreezeSuccessOutCount(sysBankCardFlowEntity.getDayFreezeSuccessOutCount()+1);
            sysBankCardFlowEntityMapper.updateById(sysBankCardFlowEntity);

        }else {
            // bcId为空
            Integer txnMode = sysFxOrderChildEntity.getTxnMode();
            // 根据tx_mode属性找到第三方支付设置
            SysThirdPartySettingEntity sysThirdPartySettingEntity = sysThirdPartySettingMapper.selectList(new LambdaQueryWrapper<SysThirdPartySettingEntity>()
                    .eq(SysThirdPartySettingEntity::getTxnMode, txnMode)
                    .eq(SysThirdPartySettingEntity::getType, 4)
                    .eq(SysThirdPartySettingEntity::getMerchantId, 0)).stream().findFirst().orElse(null);
            // 检查请求金额范围
            if (sysFxOrderChildEntity.getRequestAmount().compareTo(sysThirdPartySettingEntity.getTradeMax())>0||sysFxOrderChildEntity.getRequestAmount().compareTo(sysThirdPartySettingEntity.getTradeMin())<0){
                throw new BusinessException("单笔金额超出范围");
            }
        }
        // 更新子下发数据
        sysFxOrderChildEntity.setIsPressButton(1);
        sysFxOrderChildEntity.setStatus(6);
        sysFxOrderChildMapper.updateById(sysFxOrderChildEntity);
        // 重新获取返回类数据SysFxOrderChildResp
        SysFxOrderChildResp sysFxOrderChildResp=sysFxOrderChildMapper.getSysFxOrderChild(sysFxOrderChildRetryReq.getFxAltId());

        // 创建sys_fx_order_log表中的数据
        SysFxOrderLogEntity sysFxOrderLogEntity1=new SysFxOrderLogEntity();
        sysFxOrderLogEntity1.setFxOrderChildId(sysFxOrderChildEntity.getId());
        sysFxOrderLogEntity1.setType(1);
        sysFxOrderLogEntity1.setCreatedAt(new Date());
        sysFxOrderLogEntity1.setUpdatedAt(new Date());
        sysFxOrderLogEntity1.setCreator(userName);
        sysFxOrderLogEntity1.setUpdater(userName);

        return ApiResp.sucess(sysFxOrderChildResp);
    }

    /**
     * 检查是否可以重试
     * @param sysFxOrderChildEntity
     * @return
     */
    private boolean retryReady( SysFxOrderChildEntity sysFxOrderChildEntity){
        // 获取下发数据
        SysFxOrderEntity fxOrderEntity = sysFxOrderEntityMapper.selectById(sysFxOrderChildEntity.getFxOrderMainId());
        return sysFxOrderChildEntity.getStatus()==4
                &&sysFxOrderChildEntity.getIsPressButton()!=1
                &&sysFxOrderChildEntity.getRetryTimes()<2
                &&(fxOrderEntity.getStatus()==FxConstant.STATUS_PENDING||fxOrderEntity.getStatus()==FxConstant.STATUS_PROCESSING);
    }

    /**
     * 为excel表格封装数据
     *
     * @param sysFxOrderChildList
     * @return
     */
    private List<SysFxOrderChildExcelModel> addDateForExcel(List<SysFxOrderChildResp> sysFxOrderChildList) {
        return sysFxOrderChildList.stream().map(i -> {
            SysFxOrderChildExcelModel s = new SysFxOrderChildExcelModel();
            s.setMasterId(i.getAltFxId());
            s.setSubId(i.getAltId());
            s.setPrevious(i.getPrevAltId());
            s.setMerchant(i.getShCode() + "-" + i.getShName());
            s.setFrom(i.getFromAccountCode() + "\n" + i.getBcMobileName());
            int length = i.getToCardNumber().length();
            String s1 = length >= 5 ? i.getToCardNumber().substring(length - 5) : i.getToCardNumber();
            s.setTo(i.getShName() + "/" + i.getToBank() + "-" + s1 + "-" + i.getToMan());
            s.setAmount(i.getRequestAmount());
            s.setBankFee(i.getBankFee());
            s.setPayAmount(i.getPaidAmount());
            s.setPaymentType(i.getVndPaymentMethod() + "\n" + i.getVndOtp());
            s.setInfo("Note/备注：" + i.getNote() + "\n" + "Postscript/附言：" + i.getPostscript());
            s.setStatus(getSysFxOrderStatusNote(i.getStatus()));
            s.setStep(i.getStep());
            s.setCreated(i.getCreatedAt());
            s.setUpdated(i.getUpdatedAt());
            s.setCreatedBy(i.getCreatedMan());
            s.setUpdateBy(i.getUpdateMan());
            s.setMessage("VBS #" + i.getVbId() + "\n" + i.getMessage());
            return s;
        }).collect(Collectors.toList());
    }


    /**
     * @param sysFxOrderLogEntities 子下发操作表集合
     * @param fxOrderEntity         下发返回类
     * @param sysFxOrderChildResp   子下发返回类
     * @param loginUserName         登陆用户名
     * @return 0: 可按, 1: 已按(disabled), 2: 不顯示
     */
    public Integer getCheckButtonStatus(List<SysFxOrderLogEntity> sysFxOrderLogEntities, SysFxOrderEntity fxOrderEntity, SysFxOrderChildResp sysFxOrderChildResp, String loginUserName) {
        // (子下发状态为4，is_press_button=0，,retry_times < 2,action === null，父下发状态在（1，2）)==false时时返回2（优先级最高）
        boolean retryReady = sysFxOrderChildResp.getStatus() == FxConstant.STATUS_MANUAL_PROCESS && sysFxOrderChildResp.getIsPressButton() == 0 && sysFxOrderChildResp.getRetryTimes() < 2 && sysFxOrderChildResp.getAction() == null && (fxOrderEntity.getStatus() == FxConstant.STATUS_PENDING || fxOrderEntity.getStatus() == FxConstant.STATUS_PROCESSING);
        if (!retryReady) {
            return 2;
        } else {
            // 获取子下发操作log的type=2的第一个created_man和登录用户名对比
            String creator = sysFxOrderLogEntities.stream().filter(item -> item.getType() == 2).findFirst().map(SysFxOrderLogEntity::getCreator).orElse(null);
            if (StringUtils.isEmpty(creator)) {
                return 0;
            } else if (StringUtils.isNotBlank(creator) && creator.equals(loginUserName)) {
                return 1;
            } else {
                return 2;
            }
        }
    }

    /**
     * @param sysFxOrderLogEntities 子下发操作表集合
     * @param fxOrderEntity         下发类
     * @param sysFxOrderChildResp   子下发返回类
     * @param loginUserName         登陆用户名
     * @return boolean
     */
    public boolean getRetryButtonStatus(List<SysFxOrderLogEntity> sysFxOrderLogEntities, SysFxOrderEntity fxOrderEntity, SysFxOrderChildResp sysFxOrderChildResp, String loginUserName) {

        //  检查当前是否登录，未登录返回false
        if (loginUserName == null) {
            return false;
        } else {
            //  retryReady==true
            boolean retryReady = sysFxOrderChildResp.getStatus() == FxConstant.STATUS_MANUAL_PROCESS && sysFxOrderChildResp.getIsPressButton() == 0 && sysFxOrderChildResp.getRetryTimes() < 2 && sysFxOrderChildResp.getAction() == null && (fxOrderEntity.getStatus() == FxConstant.STATUS_PENDING || fxOrderEntity.getStatus() == FxConstant.STATUS_PROCESSING);
            // 子下发操作log类型为0时created_man！=当前登录用户
            boolean flag1 = sysFxOrderLogEntities.stream().filter(item -> item.getType() == 0 && !item.getCreator().equals(loginUserName)).count() > 0;
            // 子下发操作log卡类型为1的数据不存在
            boolean flag2 = sysFxOrderLogEntities.stream().filter(item -> item.getType() == 1).count() == 0;
            // 三个条件都满足才为true
            return retryReady && flag1 && flag2;
        }
    }


    /**
     * 获取isRunmon数据
     * @param sysFxOrderChildResp
     * @return
     */
    private Boolean getIsRunMonStatus(SysFxOrderChildResp sysFxOrderChildResp) {
        //   'is_runMon' => $row->is_entry === FX110::1 ? false : $row->is_runmon,
        //  子下发is_entry状态为1时IsRunMon=false，否则判断isRunMon
        if (sysFxOrderChildResp.getIsEntry() != null && sysFxOrderChildResp.getIsEntry() != 1) {
            if (sysFxOrderChildResp.getTpiId() != null && sysFxOrderChildResp.getTpiId() > 0) {
                if ((sysFxOrderChildResp.getStatus() == FxConstant.STATUS_PENDING || sysFxOrderChildResp.getStatus() == FxConstant.STATUS_PROCESSING || sysFxOrderChildResp.getStatus() == FxConstant.STATUS_MANUAL_PROCESS) && (sysFxOrderChildResp.getCreatedAt() != null && getDateDiff(sysFxOrderChildResp.getCreatedAt()) >= 60)) {
                    return true;
                }
                if ((sysFxOrderChildResp.getStatus() == FxConstant.STATUS_PENDING || sysFxOrderChildResp.getStatus() == FxConstant.STATUS_PROCESSING) && (sysFxOrderChildResp.getCreatedAt() != null && getDateDiff(sysFxOrderChildResp.getCreatedAt()) >= 900)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 计算时间差值（以秒为单位）
     * @return
     */
    private long getDateDiff(Date date) {

        return (new Date().getTime() - date.getTime()) / 1000;
    }

    /**
     * 根据子下发状态判断下发状态(中文注释)
     */
    public String getSysFxOrderStatusNote(Integer status) {
        switch (status) {
            case 1:
                return "Pending–等待机器人跑";
            case 2:
                return "Processing–机器人正在跑";
            case 3:
                return "Completed–成功交易";
            case 4:
                return "Manual process–失败后的手动操作,人工可操作成成功或失败(如果交易试成功的)";
            default:
                return "Failed–失败, 不可更改状态 BS200";
        }
    }


}




